/**
 * 启动服务器，提供 web 服务
 */

var static = require('node-static');
var http = require('http');
var path = require('path');
var co = require('co');

let port = 4050;
const MAX_TRY = 1;

const StaticServer = function (root) {
  this.root = root;
  this.id = root.split(/[\\\/]+/).slice(-1)[0];
  this.sockets = [];
}
function createStaticServer(path, port) {
  return new Promise((resolve, reject) => {
    try{
      var fileServer = new static.Server(path);
      var server = http.createServer((request, response) => {
          try {
            request.addListener('end', function () {
              fileServer.serve(request, response);
            }).resume();
          } catch (createServerError) {
            console.error(createServerError);
            throw createServerError;
          }
        }).listen(port);
        server.addListener('connection', socket => {
          this.sockets.push(socket);
        });
        resolve(server);
    } catch(err) {
      console.error(err);
      reject(err);
    }
  });
};
StaticServer.prototype = {
  servers: {},
  /**
   * 启动服务器
   * @param {string} id 目录id
   */
  start() {
    let tryTime = 0;
    return new Promise((resolve, reject) => {
      if (this.servers[this.id]) {
        return resolve(this.servers[this.id]);
      }
      this.port = port;
      co(function* () {
        do {
          try {
            this.server = yield createStaticServer.call(this, path.join(this.root), port);
            this.servers[this.id] = this;
            resolve(this);
            break;
          } catch(err) {
            console.error(err);
            console.error(`${port}被占用`);
          } finally {
            port += 1;
            tryTime += 1;
          }
        } while (tryTime < MAX_TRY);
      }.bind(this));
    });
  },
  /**
 * 关闭服务器
 */
  shutdown() {
    return new Promise((resolve, reject) => {
      try {
        this.sockets.forEach(socket => {
          socket.destroy();
        })
        this.servers[this.id].server.close(() => {
          delete this.servers[this.id];
          resolve(this.id);
        });
      } catch (err) {
        console.error(err);
        reject(err);
      }
    });
  }
}

module.exports = StaticServer;
